use tokio::{
    io::{AsyncReadExt, AsyncWriteExt},
    net::TcpListener,
};

pub fn main() {
    //单线程即可处理多个连接任务
    let mut builder = tokio::runtime::Builder::new_current_thread();
    let res = builder.enable_io().build().unwrap().block_on(doMain());
    res.unwrap();
}
async fn doMain() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;

    println!("server running on 8080");
    loop {
        let (mut socket, _) = listener.accept().await?;

        let addr = socket.peer_addr().unwrap();
        println!("accepted connection : {}", addr);

        tokio::spawn(async move {
            let mut buf = [0; 1024];

            // In a loop, read data from the socket and write the data back.
            loop {
                let n = match socket.read(&mut buf).await {
                    // socket closed
                    Ok(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };

                println!("from:{} :{:?}", addr, String::from_utf8_lossy(&buf[0..n]));

                // Write the data back
                if let Err(e) = socket.write_all(&buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}
